home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS01.ADF / C / GfxMem.c < prev    next >
C/C++ Source or Header  |  1985-12-04  |  12KB  |  387 lines

  1. /*
  2. From louie@trantor.UMD.EDU Thu Nov 28 16:19:27 1985
  3. Subject: GfxMem.c - graphical memory usage (New Version)
  4. Date: 28 Nov 85 22:19:27 GMT
  5. Organization: Rutgers Univ., New Brunswick, N.J.
  6.  
  7. From: Louis A. Mamakos <louie@trantor.UMD.EDU>
  8.  
  9. Here's a new and much improved version of my GfxMem.c program.  It has been 
  10. heavily revised since the last version that was distributed over the 
  11. info-amiga@red.rutgers.edu mailing list and net.micro.amiga newsgroup.  The 
  12. display updating is now much more crisp, and I'm now using the timer.device 
  13. rather than the AmigaDOS Delay() subroutine.  There was a note that the 
  14. previous version could trash a disk while running the READ program.  I tested 
  15. the new version while downloading a copy of GfxMem.c (to make sure it got to 
  16. our VAX ok), and things seemed to run just fine.  Just compile with the 
  17. Lattice C compiler and go.  You should see two compilation warnings; these 
  18. can be ignored.
  19.  
  20. **** Soapbox time ****
  21. As one of the few folks that posted any amiga programs so far, let me cast
  22. my vote to SOURCE POSTINGS of programs rather than BINHEXed versions.  We
  23. can learn a lot from each other, and hopefully avoid making the same
  24. stupid errors or inventing the same wheels over and over again.
  25. **** End Soapbox ****
  26.  
  27. The program displays two bar graphics, one for "CHIP" memory, and one for
  28. "FAST" memory.  Each bar graph is split into two colors; part for memory in
  29. use and part for memory free.  As the window is resized, the graphics are
  30. rescaled to the sized of the window.  If you find any bugs or have any 
  31. neat features that you'd like to see, let me know. 
  32.  
  33. Louis A. Mamakos  WA3YMH    Internet: louie@TRANTOR.UMD.EDU
  34.   University of Maryland, Computer Science Center - Systems Programming
  35.  
  36. Anyway, here it is:
  37. */
  38.  
  39. /*
  40.  *  gfxmem.c  - graphically display available memory.  Quick program
  41.  *     that's a freebie.  Give it to anyone you please, just don't sell it.
  42.  *
  43.  *       Version 0.0 - initial version, released on INFO-AMIGA.
  44.  *       Version 0.1 - added numeric indication of available and used memory
  45.  *                     in bar graphs.
  46.  *       Version 0.2 - added condition compilation for timer.device code.  If
  47.  *                     I can figure out how to make it create timer signals,
  48.  *                     then I can define USE_TIMER for much more prompt
  49.  *                     response to window sizing attempts.  Oh well.
  50.  *       Version 0.3 - removed conditional compilation for timer.device
  51.  *                     code.  We now use the timer, and all seems well.
  52.  *       Version 0.4 - calculate character data placement according to
  53.  *                     display preferences.  Check for updated preferences
  54.  *                     while running.
  55.  *  TODO:
  56.  *       Add menu selection package to display Kbytes or percent of memory
  57.  *       used and free.
  58.  *
  59.  *       Add requestor to display statistics like min and max for free and
  60.  *       avail, time running, etc..
  61.  *
  62.  *
  63.  *                 Copyright (C) 1985,
  64.  *                 Louis A. Mamakos
  65.  *                 Software & Stuff
  66.  */
  67.  
  68. #define  PROG_VER "GfxMem 0.4 "
  69.  
  70. #include <exec/types.h>
  71. #include <exec/nodes.h>
  72. #include <exec/lists.h>
  73. #include <exec/exec.h>
  74. #include <exec/execbase.h>
  75. #include <exec/ports.h>
  76. #include <exec/devices.h>
  77. #include <exec/memory.h>
  78. #include <devices/timer.h>
  79. #include <hardware/blit.h>
  80. #include <graphics/copper.h>
  81. #include <graphics/regions.h>
  82. #include <graphics/rastport.h>
  83. #include <graphics/gfxbase.h>
  84. #include <graphics/gfxmacros.h>
  85. #include <graphics/gels.h>
  86. #include <intuition/intuition.h>
  87.  
  88. extern struct ExecBase *SysBase;
  89. struct IntuitionBase *IntuitionBase;
  90. struct GfxBase *GfxBase;
  91. struct MsgPort *timerport, *CreatePort();
  92. struct timerequest timereq;
  93.  
  94. struct NewWindow NewWindow = {
  95.    10, 10, 450, 50,           /* sizes */
  96.    -1, -1,                    /* pens */
  97.    CLOSEWINDOW | ACTIVEWINDOW | SIZEVERIFY |
  98.                  NEWSIZE | NEWPREFS | REFRESHWINDOW,   /* IDCMP flags */
  99.    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH,
  100.    NULL, NULL,                /* gadget, checkmark */
  101.    PROG_VER,                  /* title */
  102.    NULL, NULL,                /* screen, bitmap */
  103.    100, 30, 640, 100,         /* min and max sizing */
  104.    WBENCHSCREEN               /* on the workbench screen */
  105. };
  106.  
  107. ULONG    AvailMem ();
  108. ULONG    ChipMax, FastMax, ChipFree, FastFree;
  109. ULONG    ChipLargest, FastLargest;
  110. int      dont_draw, char_size;
  111.  
  112. /*
  113.  *  maxsize -- determine the total maximum size for all regions
  114.  *   of the given type.  This code must be executed while
  115.  *   FORBIDDEN (it accesses shared system structures).
  116.  */
  117. ULONG
  118. maxsize (t)
  119.     unsigned long t;
  120. {
  121.     /* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */
  122.     ULONG size = 0;
  123.     struct MemHeader *mem;
  124.     struct ExecBase *eb = SysBase;
  125.  
  126.     for (mem = (struct MemHeader *) eb->MemList.lh_Head;
  127.                         mem->mh_Node.ln_Succ; mem = mem->mh_Node.ln_Succ)
  128.        if (mem -> mh_Attributes & t)
  129.           size += ((ULONG) mem->mh_Upper - (ULONG) mem->mh_Lower);
  130.     return size;
  131. }
  132.  
  133. getsizes()
  134. {
  135.    if (ChipMax == 0) {  /* only do this once */
  136.       Forbid ();
  137.       ChipMax = maxsize (MEMF_CHIP);
  138.       FastMax = maxsize (MEMF_FAST);
  139.       Permit();
  140.    }
  141.    ChipFree = AvailMem (MEMF_CHIP);
  142.    ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST);
  143.    FastFree = AvailMem (MEMF_FAST);
  144.    FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST);
  145. }
  146.  
  147. starttimer()
  148. {
  149.    timereq.tr_time.tv_secs = 1;
  150.    timereq.tr_time.tv_micro = 0;
  151.    timereq.tr_node.io_Command = TR_ADDREQUEST;
  152.    timereq.tr_node.io_Flags = 0;
  153.    timereq.tr_node.io_Error = 0;
  154.    timereq.tr_node.io_Message.mn_ReplyPort = timerport;
  155.    SendIO((char *) &timereq.tr_node);
  156. }
  157.  
  158. /*
  159.  *  This function is called during startup and when new preferences are
  160.  *  selected.  Get the font size from the Preferences structure.
  161.  */
  162. newprefs()
  163. {
  164.    char FontHeight;
  165.  
  166.    GetPrefs(&FontHeight, sizeof (FontHeight));
  167.    switch (FontHeight) {
  168.    case TOPAZ_SIXTY:
  169.       char_size = 11;
  170.       break;
  171.  
  172.    case TOPAZ_EIGHTY:
  173.       char_size = 8;
  174.       break;
  175.  
  176.    default:
  177.       char_size = 12;
  178.    }
  179. }
  180.  
  181.  
  182. /*
  183.  *  Main function.  Call intution to create a new window for us on the
  184.  *  screen.  Go from there.
  185.  */
  186. main(argc, argv)
  187.    int argc;
  188.    char **argv;
  189. {
  190.    struct Window *w;
  191.    struct IntuiMessage *msg, *GetMsg();
  192.    int waitmask;
  193.  
  194.    timerport = NULL;
  195.    IntuitionBase = (struct IntuitionBase *)
  196.                    OpenLibrary("intuition.library", 0);
  197.    if (IntuitionBase == NULL)
  198.       exit(1);
  199.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  200.    if (GfxBase == NULL) {
  201.       CloseLibrary(IntuitionBase);
  202.       exit(2);
  203.    }
  204.  
  205.    if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) {
  206.       CloseLibrary(GfxBase);
  207.       CloseLibrary(IntuitionBase);
  208.       exit(3);
  209.    }
  210.    if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
  211.       CloseWindow(w);
  212.       CloseLibrary(GfxBase);
  213.       CloseLibrary(IntuitionBase);
  214.       exit(5);
  215.    }
  216.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
  217.       DeletePort(timerport);
  218.       CloseWindow(w);
  219.       CloseLibrary(GfxBase);
  220.       CloseLibrary(IntuitionBase);
  221.       exit(4);
  222.    }
  223.  
  224.    newprefs();
  225.    redraw(w, TRUE);
  226.    starttimer();
  227.    waitmask = (1 << w->UserPort->mp_SigBit) |
  228.               (1 << timerport->mp_SigBit);
  229.    for(;;) {
  230.       Wait(waitmask);
  231.       while (msg = GetMsg(w->UserPort)) {
  232.          switch (msg->Class) {
  233.          case CLOSEWINDOW:
  234.             ReplyMsg(msg);
  235.             AbortIO(&timereq);
  236.             CloseDevice(&timereq);
  237.             DeletePort(timerport);
  238.             CloseWindow(w);
  239.             CloseLibrary(GfxBase);
  240.             CloseLibrary(IntuitionBase);
  241.             exit(0);
  242.  
  243.          case REFRESHWINDOW:
  244.             BeginRefresh(w);
  245.             dont_draw = 0;
  246.             redraw(w, TRUE);
  247.             EndRefresh(w, TRUE);
  248.  
  249.          case ACTIVEWINDOW:
  250.             /* when window is active, display version */
  251.             SetWindowTitles(w, -1, 
  252.                             "Graphical memory display by Louis A. Mamakos");
  253.             break;
  254.  
  255.          case NEWSIZE:
  256.             dont_draw = 0;
  257.             redraw(w, TRUE);
  258.             break;
  259.  
  260.          case SIZEVERIFY:
  261.             dont_draw = 1;
  262.             break;
  263.  
  264.          case NEWPREFS:
  265.             newprefs();
  266.             redraw(w, TRUE);
  267.             break;
  268.          }
  269.          ReplyMsg(msg);
  270.       } /* while */
  271.  
  272.       if (GetMsg(timerport)) {
  273.          redraw(w, FALSE);
  274.          starttimer();
  275.       }
  276.    } /* for */
  277. }
  278.  
  279.  
  280. #define TOP w->BorderTop
  281. #define BOTTOM w->Height - w->BorderBottom
  282. #define LEFT w->BorderLeft
  283. #define RIGHT w->Width - w->BorderRight
  284. #define GUTTER 3        /* pixels of veritical spacing between bars */
  285.  
  286. /*
  287.  *  Redraw all of the stuff in the window.
  288.  */
  289. redraw(w, refresh)
  290.    struct Window *w;
  291.    int refresh;
  292. {
  293.    register struct RastPort *rp = w->RPort;
  294.    register short x_min, y_min, x_max, y_max;
  295.    static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale;
  296.    static long old_chipfree, old_fastfree;
  297.    char txt[10];
  298.  
  299.    if (dont_draw)
  300.       return 0;
  301.    getsizes();
  302.    if (refresh) {
  303.       SetAPen(rp, 2);
  304.       SetBPen(rp, 2);
  305.       SetOPen(rp, 2);
  306.       RectFill(rp, LEFT, TOP, RIGHT, BOTTOM);
  307.       /*  recalculate the spacing paramters for this sized window */
  308.       AvailWidth = w->Width - w->BorderRight - w->BorderLeft;
  309.       AvailHeight = w->Height - w->BorderTop - w->BorderBottom;
  310.       HorizSpace = AvailWidth/20; /* use 5% of available space as margin */
  311.       AvailWidth -= HorizSpace * 2;
  312.       Thickness = (AvailHeight - GUTTER*3) / 2;
  313.       if (ChipMax > FastMax)
  314.          Scale = ChipMax/AvailWidth;
  315.       else
  316.          Scale = FastMax/AvailWidth;
  317.    } else
  318.       if (old_chipfree == ChipFree && old_fastfree == FastFree)
  319.          return 0;
  320.    old_chipfree = ChipFree;
  321.    old_fastfree = FastFree;
  322.    SetAPen(rp, 3);
  323.    SetOPen(rp, 1);
  324.    SetBPen(rp, 2);
  325.    x_min = HorizSpace;
  326.    y_min = TOP + GUTTER;
  327.    x_max = x_min + (ChipMax - ChipFree)/Scale;
  328.    y_max = y_min + Thickness;
  329.    RectFill(rp, x_min, y_min, x_max, y_max);
  330.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  331.       sprintf(txt, "%4dK", (ChipMax - ChipFree) >> 10);
  332.       SetAPen(rp, 1);
  333.       SetBPen(rp, 3);
  334.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  335.       Text(rp, txt, 5);
  336.    }
  337.    x_min = x_max;
  338.    x_max = x_min + ChipFree/Scale;
  339.    SetAPen(rp, 0);
  340.    RectFill(rp, x_min, y_min, x_max, y_max);
  341.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  342.       sprintf(txt, "%4dK", ChipFree>>10);
  343.       SetAPen(rp, 1);
  344.       SetBPen(rp, 0);
  345.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  346.       Text(rp, txt, 5);
  347.    }
  348.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  349.       SetAPen(rp, 1);
  350.       SetBPen(rp, 2);
  351.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 4);
  352.       Text(rp, "C", 1);
  353.    }
  354.    x_min = HorizSpace;
  355.    x_max = x_min + (FastMax - FastFree)/Scale;
  356.    y_min = y_max + GUTTER;
  357.    y_max = y_min + Thickness;
  358.    SetAPen(rp, 3);
  359.    RectFill(rp, x_min, y_min, x_max, y_max);
  360.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  361.       sprintf(txt, "%4dK", (FastMax - FastFree) >> 10);
  362.       SetAPen(rp, 1);
  363.       SetBPen(rp, 3);
  364.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  365.       Text(rp, txt, 5);
  366.    }
  367.    x_min = x_max;
  368.    x_max = x_min + FastFree/Scale;
  369.    SetAPen(rp, 0);
  370.    RectFill(rp, x_min, y_min, x_max, y_max);
  371.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  372.       sprintf(txt, "%4dK", FastFree>>10);
  373.       SetAPen(rp, 1);
  374.       SetBPen(rp, 0);
  375.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  376.       Text(rp, txt, 5);
  377.    }
  378.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  379.       SetAPen(rp, 1);
  380.       SetBPen(rp, 2);
  381.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 3);
  382.       Text(rp, "F", 1);
  383.    }
  384. }
  385.  
  386.  
  387.